"""
@Author    : ghenyar
@Time      : 2025/9/3 16:20
@File      : role_service
@Desc      : 角色管理
"""

from typing import List

from sqlalchemy.ext.asyncio import AsyncSession

from app.admin.schemas.role import RoleSerialize, RoleSchema
from app.admin.service.menu_service import MenuService
from app.common.model_querier import ModelQuerier
from app.common.page_result import PageResult

from app.common.tools import select_orm

from app.models.admin_model import AdminRoleModel
from app.models.role_model import RoleModel
from app.utils.log import LoggingUtil


class RoleService:
    # 日志
    logger = LoggingUtil(f"{__name__}.RoleService")

    @classmethod
    async def lists_data(cls, db: AsyncSession, page: int, pageSize: int, key: str = None) -> PageResult:
        """
        角色列表
        :param db: 数据库会话
        :param page: 当前页码
        :param pageSize: 每页显示条数
        :param key: 关键字
        :return:
        """
        # 构建查询条件
        conditions = []
        if key:
            conditions.append(RoleModel.name.contains(key))

        # 查询及分页处理
        role = ModelQuerier(db, RoleModel)
        if conditions:
            role = role.where(*conditions)

        role_list = await role.order_by(RoleModel.created_at.desc()).pagination(page, pageSize)

        # 处理数据
        async def role_format(role_item):
            role_orm = await RoleSerialize.from_orm(role_item)
            role_orm.permission_list = await MenuService.get_menus_by_permission(db, role_orm.permissions)
            return role_orm

        role_list.items = [await role_format(role) for role in role_list.items]
        return role_list

    @classmethod
    async def create_or_update(cls, db: AsyncSession, data: RoleSchema) -> bool:
        """
        新增，编辑角色
        :param db:
        :param data:
        :return:
        """
        permissions_str = ",".join(map(str, data.permissions))
        role_data = {
            "name": data.name,
            "desc": data.desc,
            "permissions": permissions_str
        }
        try:
            if data.id is None or data.id == 0:
                role = RoleModel(**role_data)
                db.add(role)
                await db.commit()
                return True
            else:
                up_success = await ModelQuerier(db, RoleModel).where(RoleModel.id == data.id).update_one(**role_data)
                return bool(up_success)
        except Exception as e:
            await db.rollback()
            cls.logger.error(f"新增，编辑角色失败！{str(e)}")
            return False

    @classmethod
    async def del_role(cls, db: AsyncSession, role_id: int) -> bool:
        """
        删除角色
        :param db:
        :param role_id:
        :return:
        """
        try:
            role = await ModelQuerier(db, RoleModel).where(RoleModel.id == role_id).delete()
            return bool(role)
        except Exception as e:
            await db.rollback()
            cls.logger.error(f"删除角色失败！{str(e)}")
            return False

    @classmethod
    async def check_bound_role(cls, db: AsyncSession, role_id: int) -> bool:
        """
        检查是否绑定管理员
        :param db:
        :param role_id: 角色id
        :return:
        """
        return await ModelQuerier(db, AdminRoleModel).where(AdminRoleModel.role_id == role_id).exists()

    @staticmethod
    async def get_role_for_select(db: AsyncSession) -> List[dict[str, str]]:
        """
        为下拉框
        :return:
        """
        roles = await ModelQuerier(db, RoleModel).order_by(RoleModel.id.asc()).only(RoleModel.id,
                                                                                    RoleModel.name).get_all(
            as_dict=True)
        return select_orm(roles, "name", "id")

    @staticmethod
    async def get_role_permissions_by_role_ids(db: AsyncSession, role_ids: List[int]) -> List[int]:
        """
        根据批量角色id获取角色权限
        :param db:
        :param role_ids: 角色id
        :return:
        """
        role_perm = await ModelQuerier(db, RoleModel).where(RoleModel.id.in_(role_ids)).get_list(RoleModel.permissions)
        permissions_list = list(dict.fromkeys(int(num) for item in role_perm for num in item.split(',')))
        return permissions_list

    @classmethod
    async def get_role_by_ids(cls, db: AsyncSession, role_ids: List[int]) -> List[RoleSerialize]:
        """
        根据批量角色id获取角色信息
        :param db: 数据库会话
        :param role_ids: 角色id
        :return: 角色信息
        """
        roles_list = await ModelQuerier(db, RoleModel).where(RoleModel.id.in_(role_ids)).get_all()
        role_list = [await RoleSerialize.from_orm(role) for role in roles_list]
        return role_list
